package com.pingan.generator.api.service.impl;


import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.pingan.generator.api.entity.ColInfo;
import com.pingan.generator.api.entity.InterFaceInfo;
import com.pingan.generator.api.entity.mapper.ColInfoMapper;
import com.pingan.generator.api.entity.mapper.InterFaceMapper;
import com.pingan.generator.api.service.ApiQueryService;


@Service("apiQueryService")
public class ApiQueryServiceImpl  implements ApiQueryService {
	@Autowired
	private InterFaceMapper interfaceMapper;
	@Autowired
	private ColInfoMapper colInfoMapper;
	
    
	@Override
	public List<Map<String,Object>> getApiList() throws Exception {
		List<InterFaceInfo> list=interfaceMapper.getApiList();
		List<Map<String,Object>> retList=new ArrayList<Map<String,Object>>();
	    if(list!=null && list.size()>0){
	    	Set<String> set=new HashSet<String>();
	    	for(InterFaceInfo dto:list){
	    		String url=dto.getUrl();
	    		String firstUrl=url.substring(1,url.lastIndexOf("/"));
	    		set.add(firstUrl);
	    	}
	    	
	    	for(String fir:set){
	    		Map<String,Object> retMap=new HashMap<String,Object>();
	    		List<Map<String,Object>> sedList=new ArrayList<Map<String,Object>>();
	    		for(InterFaceInfo dto:list){
	    			String url=dto.getUrl();
	    		    if(url.indexOf(fir)!=-1){
	    		    	Map<String,Object> sedMap=new HashMap<String,Object>();
	    		    	sedMap.put("id", dto.getId());
	    		    	sedMap.put("url", url);
	    		    	sedMap.put("name", dto.getName()==null?"":dto.getName());
	    		    	sedMap.put("type", dto.getType()==null?"1":dto.getType());
	    		    	Timestamp sureDate=dto.getSureDate();
	    		    	if(sureDate==null){  //说明还没确认
	    		    		sedMap.put("sure", "0");//未确认
	    		    	}else{
	    		    		sedMap.put("sure", "1");//已确认
	    		    	}
	    		    	sedList.add(sedMap);
	    		    }
	    		}
	    		retMap.put("firList", sedList);
	    		retMap.put("firName", fir);
	    		retList.add(retMap);
	    	}
	    }
		
		return retList;
	}
	
	@Override
	public void sureApi(long id) throws Exception {
		interfaceMapper.sureAPI(id);
	}

	@Override
	public Map<String,Object> getApiDetail(long interfaceId,String apiType) throws Exception {
		Map<String,Object> reqMap=new HashMap<String,Object>();
		reqMap.put("interfaceId", interfaceId);//字段所属接口ID
		if("3".equals(apiType)||"1".equals(apiType)){
			reqMap.put("colType", "1");//字段类型  1-新增
		}else{
			reqMap.put("colType", "2");//2-废弃
		}
		/*
		 * 查询结果包括两部分
		 * type=1的最新字段（apiType=1,2,3都要求）
		 * type=2的字段----接口确认时间到当前系统时间之内的已废弃字段(apiType=3时才考虑)
		 */
		List<Map<String,Object>> list=colInfoMapper.getApiDetail(reqMap);
		if("3".equals(apiType)){
			reqMap.put("apiType",apiType);
			List<Map<String,Object>>  tempList=colInfoMapper.getApiDetailOther(reqMap);
			if(tempList!=null && tempList.size()>0){
				list.addAll(tempList);
				System.out.println("添加废弃元素ok");
			}
		}
		
		Map<String,Object> retMap=new HashMap<String,Object>();//保存入参和出参
		List<Map<String,Object>> reqList=new LinkedList<Map<String,Object>>();//保存入参
		List<Map<String,Object>> resList=new LinkedList<Map<String,Object>>();//保存出参
		if(list!=null && list.size()>0){
			for(Map<String,Object> map:list){
				Map<String,Object> sonMap=new HashMap<String,Object>();
				String isList=String.valueOf(map.get("isList"));//是否list--泛型
				String isObject=String.valueOf(map.get("isObject"));
				String col=String.valueOf(map.get("col"));
				long id=(Long)map.get("id");
				sonMap.put("id", id);
				sonMap.put("col", col);
				sonMap.put("colName", map.get("colName")==null?"":map.get("colName"));
				sonMap.put("attr", map.get("attr"));
				sonMap.put("isNull", map.get("isNull")==null?"":map.get("isNull"));
				sonMap.put("isObject", map.get("isObject")==null?"":map.get("isObject"));
				sonMap.put("isList", isList);
				sonMap.put("length", map.get("length")==null?50:map.get("length"));
				sonMap.put("reqOrResp", map.get("reqOrResp"));
				Timestamp sureDate=(Timestamp)map.get("sureDate");//确认时间
				
				/*
				 * 根据所属接口id，字段名称,参数类型(出参还是入参),所属上层的id来比较最新一期和往期最近一期的
				 * 字段变化(字段类型，长度，是否非空，集合等)
				 */
				String normal_key=(String)map.get("normal");
				String compareType="0";//正常比较状态
				if(!"1".equals(normal_key)){
					if("3".equals(apiType) && sureDate !=null ){  //apiType=1 或者apiType=2的时候都只需要正常显示该接口下字段
						compareType=compareParam(map,sureDate);
					}
				}else{
					compareType="7";
				}
				System.out.println("元素:"+col+"  修改类型为::"+compareType);
				sonMap.put("compareType", compareType);
				
                if(checkParam(isList)||checkParam(isObject)){ //泛型元素
                	List<Map<String,Object>> sonList=querySonParam(id,apiType,sureDate);
					sonMap.put("sonList", sonList);
				}
                
				
				String reqOrResp=String.valueOf(map.get("reqOrResp"));//是入参还是出参
				if("1".equals(reqOrResp)){//入参
					reqList.add(sonMap);
				}else{                    //出参
					resList.add(sonMap);
					
				}
			}
		}
		retMap.put("input", reqList);
		retMap.put("output", resList);
		
		String html=getOutputFormat(resList);
		System.out.println("html::"+html);
	   	retMap.put("outFormat", html);
		return retMap;
	}
	
	/**
	 * 字段比较:
	 *    1:接口新增字段   不用跟往期比较-标示1
	 *    2:接口字段其他属性修改：需要跟往期最近一条记录比较出具体的变化---
	 *    3:接口废弃字段   最新没有，往期最近有，只显示确认时间到当前时间的被废弃字段
	 * @param dtoMap   最新的元素
	 * @param sureDate 接口确认时间
	 * @return
	 */
	private String compareParam(Map<String,Object> dtoMap,Timestamp sureDate){
		System.out.println("最新的待比较元素 -----dtoMap：："+dtoMap);
	    Map<String,Object> reqMap=new HashMap<String,Object>();
	    reqMap.put("col", dtoMap.get("col"));//字段名称
	    reqMap.put("reqOrResp", dtoMap.get("reqOrResp"));//入参_出参
	    reqMap.put("apiId", dtoMap.get("apiId"));//关联接口id
	    reqMap.put("sureDate", sureDate);//接口确认时间
	    reqMap.put("colFatherId", dtoMap.get("colFatherId"));//所属上层元素Id
	    //reqMap.put("type", dtoMap.get("type"));
    	List<Map<String,Object>> list=colInfoMapper.findApiDetailById(reqMap);
		StringBuffer compareType=new StringBuffer("0");//正常状态
		if(list!=null && list.size()>0){
			if(list.size()==1){ //说明这个是新增的字段
				compareType.append(",1");
			}else{
				Map<String,Object> one=list.get(1);//最近的一条记录比较
				boolean attr_check=(one.get("attr")==null && dtoMap.get("attr")!=null)||(one.get("attr")!=null && dtoMap.get("attr")==null)||(one.get("attr")!=null &&dtoMap.get("attr")!=null && !one.get("attr").equals(dtoMap.get("attr")));
				if(attr_check){
					compareType.append(",2");//字段类型改变
				}
				boolean isNull_check=(one.get("is_null")==null && dtoMap.get("isNull")!=null)||(one.get("is_null")!=null && dtoMap.get("isNull")==null)||(one.get("is_null")!=null &&dtoMap.get("isNull")!=null && !one.get("is_null").equals(dtoMap.get("isNull")));
				if(isNull_check){
					compareType.append(",3");//非空约束改变
				}
				boolean isList_check=(one.get("is_list")==null && dtoMap.get("isList")!=null)||(one.get("is_list")!=null && dtoMap.get("isList")==null)||(one.get("is_list")!=null &&dtoMap.get("isList")!=null && !one.get("is_list").equals(dtoMap.get("isList")));
				if(isList_check){
					compareType.append(",4");//是否为集合改变
				}
				
				boolean isObj_check=(one.get("is_object")==null && dtoMap.get("isObject")!=null)||(one.get("is_object")!=null && dtoMap.get("isObject")==null)||(one.get("is_object")!=null &&dtoMap.get("isObject")!=null && !one.get("is_object").equals(dtoMap.get("isObject")));
				if(isObj_check){
					compareType.append(",5");//是否为对象改变
				}
				boolean len_check=(one.get("length")!=null && dtoMap.get("length")==null)||(one.get("length")==null && dtoMap.get("length")!=null)||(one.get("length")!=null && dtoMap.get("length")!=null && one.get("length")==(Long)dtoMap.get("length"));
				if(len_check){
					compareType.append(",6");//长度变化了
				}
			}
		}
    	return compareType.toString();
	}
	
	
	
	
	
	/**
	 * 出参格式化
	 * @param resList
	 * @return
	 */
	private String getOutputFormat(List<Map<String,Object>> resList){
		StringBuffer sb=new StringBuffer();
		sb.append("<span>{</span></br>");
		sb.append("<span>&nbsp;'code':0&nbsp;</span></br>");
		sb.append("<span>&nbsp;'msg':请求成功&nbsp;</span></br>");
		sb.append("<span>&nbsp;'data':&nbsp;{</span></br>");
        if(resList.size()>0){
        	formatOutResult(resList,sb,1);
		}
		sb.append("<span>&nbsp;}&nbsp;</span></br>");
		sb.append("<span>}</span></br>");
		System.out.println("返回前端的响应格式:"+sb.toString());
		return sb.toString();
	}
	  
	/**
	 * 将出参格式化
	 * @param list
	 * @param sb
	 * @param num
	 */
	private void formatOutResult(List<Map<String,Object>> list,StringBuffer sb,int num){
		String spance="";
		if(num==1){
			spance="&nbsp;&nbsp;&nbsp";
		}else if(num==2){
			spance="&nbsp;&nbsp;&nbsp;&nbsp;";
		}else if(num==3){
			spance="&nbsp;$nbsp;&nbsp;&nbsp;&nbsp;";
		}else if(num==4){
			spance="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
		}
		for(Map<String,Object> map:list){
			String col=(String)map.get("col");
			String colName=(String)map.get("colName");
			String isList=(String)map.get("isList");
			if("Y".equals(isList)){//存在子节点
				sb.append("<span>"+spance+"'"+col+"':["+spance+"</span></br>");
				List<Map<String,Object>> sonList=(List<Map<String,Object>>)map.get("sonList");
				if(sonList!=null && sonList.size()>0){
					formatOutResult(sonList,sb,num++);
				}
				sb.append("<span>"+spance+"'"+col+"':]"+spance+"</span></br>");
			}else{
				sb.append("<span>"+spance+"'"+col+"':'"+colName+"'"+spance+"</span></br>");
			}
		}
	}

    /**
     * 递归获取泛型里面的参数
     * @param fatherId
     * @param apiType
     * @param sureDate
     * @return
     */
    private List<Map<String,Object>> querySonParam(long fatherId,String apiType,Timestamp sureDate){
    	System.out.println("存在子元素----querySonParam()    fatherId:"+fatherId+"   apiType:"+apiType);
    	List<Map<String,Object>> retList=new LinkedList<Map<String,Object>>();
    	Map<String,Object> reqMap=new HashMap<String,Object>();
    	reqMap.put("colFatherId", fatherId);//归属父元素id
    	if("3".equals(apiType)){
    		reqMap.put("type", 1);//apiType=1或者 apiType=3都标识接口是正常的
    	}else{
    		reqMap.put("type", apiType);//apiType=2标识接口废弃了
    	}
    	
    	List<Map<String,Object>> list=colInfoMapper.findApiDetailById(reqMap);
    	if("3".equals(apiType)){
    		List<Map<String,Object>> otherList=colInfoMapper.findApiDetailByIdOther(reqMap);
    		if(otherList!=null && otherList.size()>0){
    			list.addAll(otherList);
    		}
    	}
    	System.out.println("父元素::"+fatherId+"  下的子元素有::"+list.size());
    	if(list!=null && list.size()>0){
    		for(Map<String,Object> dto:list){
    			Map<String,Object> sonMap=new HashMap<String,Object>();
    			
    			sonMap.put("col", dto.get("col"));
				sonMap.put("colName", dto.get("colName")==null?"":dto.get("colName"));
				sonMap.put("attr", dto.get("attr"));
				sonMap.put("isNull", dto.get("is_null")==null?"":dto.get("is_null"));
				sonMap.put("isObject", dto.get("is_object")==null?"":dto.get("is_object"));
				sonMap.put("isList", dto.get("is_list")==null?"":dto.get("is_list"));
				sonMap.put("length", dto.get("length")==null?"":dto.get("length"));
    			String normal=(String)dto.get("normal");
				/*
				 * 根据所属接口id，字段名称,参数类型(出参还是入参),所属上层的id来比较最新一期和往期最近一期的
				 * 字段变化(字段类型，长度，是否非空，集合等)
				 */
				String compareType="0";//正常比较状态
				if(!"1".equals(normal)){
					if("3".equals(apiType) && sureDate !=null ){  //apiType=1 或者apiType=2的时候都只需要正常显示该接口下字段
						Map<String,Object> map=new HashMap<String,Object>();
						map.put("col", dto.get("col"));//字段名称
						map.put("reqOrResp", dto.get("req_or_resp"));//入参_出参
						map.put("apiId", dto.get("interface_id"));//关联接口id
						map.put("colFatherId", dto.get("col_father_id"));//所属上层元素Id
						//map.put("type", dto.get("type"));
						compareType=compareParam(map,sureDate);
					}
				}else{
					compareType="7";//废弃
				}
				
				System.out.println("元素:"+dto.get("col")+"  修改类型为::"+compareType);
				sonMap.put("compareType", compareType);
				
				if(checkParam((String)dto.get("is_list"))||checkParam((String)dto.get("is_object"))){ //泛型元素
					List<Map<String,Object>> sonList=querySonParam((Long)dto.get("id"),apiType,sureDate);
    				sonMap.put("sonList", sonList);
				}
    			System.out.println("sonMap::"+sonMap);
    			retList.add(sonMap);
    		}
    	}
    	return retList;
    }
    
    
    private boolean checkParam(String param){
    	if("Y".equals(param)){
    		return true;
    	}
    	return false;
    }
    
    /**
     * 根据fatherId判断元素是否存在上层泛型元素
     * @param fatherId
     * @return
     */
	private boolean isExistFatherParam(long fatherId){
		int number=colInfoMapper.isExistFatherParam(fatherId);
		System.out.println("isExistFatherParam    size::"+number);
		if(0==number){
			return false;
		}
		return true;
	}



	

}
